<?php declare(strict_types=1);

namespace App\Services\PengYiPeng;


use App\Api\Controllers\Merchant\OrderController;
use App\Api\Controllers\Merchant\PayBaseController;
use App\Models\Device;
use App\Models\DeviceServiceProviders;
use App\Models\Order;
use App\Models\RefundOrder;
use App\Models\Store;
use App\Models\StoreAliyunAuth;
use App\Services\Count\MerchantBillCountService;
use App\Utils\AliYun\request\AlipayCommerceIotDeviceRecordsSetRequest;
use App\Utils\AliYun\request\AlipayMerchantOrderExternalPaychannelSyncRequest;
use App\Utils\AliYun\request\AlipayOpenAuthTokenAppRequest;
use Illuminate\Support\Facades\Log;

class SPILiteService
{
//    const GatewayUrl = "https://openapi.alipay.com/gateway.do";

    /**这个是皖付通网页移动应用参数
     * const AppID = "2021004190649336";
     *
     * const RsaPrivateKKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCbKQslVAQUVzH2KCSFlKumh903iwdupSBbW7J0gFBILIbUCTyFhNXGgXlOSu0Rw/XOHWy66NEHSyV0ViHLwh4qgdygpH7Avi2bDVfyKeBPWLXMr1b1cX1ALbgU15E92Sw95zCKTFCseFgomLMYv0Z1aTLTJJ/Aly4RPyHAWOcJL262hIwkYBNZhrcWmIuBRXSjOMKxM6sNsUfe+6+29pnZzGUhJSVS0+LLLgwMu0CUod6Kd/0zxj6NphbylKc2wxIAhM+co087Oxqk9aTdNKYB2SScnYweH5efXB1JOT8hXI8bU3wlr3qGepNO/WZMnW5WgV5WqfYh0balSjKPH6APAgMBAAECggEAN07FE1REc/+05nreseMR4LWzbDYZux4PT6F7Fj4a3+9HTFPSiAGWtkC2verFYLzKZONmO6X7xK7LthFx0JDscdiCjZy1Nf1Ugl2aSM8WjxIfE8w4ohsHO5ZQdNV2h2Zfd91uFw4m/6OSQT5VMPAVrIqIPG1kqKD7IdiwLkFCcaoxmvFyb+r9kFkZupEKXsDov+D22W0D8qqANlXpbL1bVnWQHrPdMxShUXaerKCtVZ2EGTk+qf11CgcJ0+ud52vOlsUBJWro5+5ICUstMOCHwWw3OVhOstJSpizkGNkBl5JrdPmeeA54jG2EF1lHB1x89VYrZzgj+FoueU4/v7VIyQKBgQDMN0eZ7sGjmj3AzcxHLsFNIrnmWY5jIV4viABl6k0DJhOUkIpXSElld4LYZ0CW7QwTE7LOdXyW7w12gXxelbxaPA4IyPpXI0ncP5CSMHbxzJGZcc8OzfWN5hl2k/wUtLcep3bkXiSHvXD+n0Ma73wBqLklKpEZvycF2dHvHJSMIwKBgQDCgU8DLhjCn0Skwdu4Dn6BVJ8BOWQQLlrug2JBoNeRxdOMBFY//NKoTgadkWN0AofkRAdn2FtDv/8k/AgwDH+wGeZ/s7GUMrvSXIyNBm2MCPbAPmT7MPcetCA6T1tzNDicWQYOA3mgnry2cJ0yE1/n8PS3qUT0nr0+wYiUeX2VJQKBgQCEtxw6RrbjOtcNGPG8BP+swHet4t+tPr82Bp2zngxEkpdBAppVVO4WGhAX0Sphq1Ygg7m9gQ7iDCNks4v+8DLDNaotPWer/4v9rfWnfAWg6MBqx1K4HVOKz1IXBN9bGYK0UkLq8N+us4fegeQbei3N6jfAlqRL5jVXERLk4V8MnwKBgQCkdVtOcAqFfM84k6VpEfBLADbVfSYrPFasdzB8FzhOTDublwsqXWXs4tRbJFQ4Ae/OxOqSFnDMbymXpvZxUhAg4TVw4ooSqXb/3jsE/ttfXTDtyZPuhC9eqaTaSMElPpFjOS6SaMPNWIpto/h2H8WmwqjYJepk/1c6Gb+W8saJdQKBgHUeYt+f8Jrg9fiTtnkvedWMhg8zsUtN4dCQkAw37n+kWOpw6V9H2UoCjB+TmbMQZKTyLeqxkXPOGDmdWNJSUxCLMqBijhkxZvvR8eNVNuVL1IAS0tQeEsgKrQEtIDoUGoC/vrY4R8pb3uVmkBArgPbSG3AHjlxNBRJGxU9gISH2";
     *
     *
     * const AlipayRasPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArq696YzJWydjfUPOtCJqAedMGVK1t3DbMRzJtiDeZNReQWWipR+Yk8kIDn5+s6NiTtvkPgIV/33WNWIgXxw+3qdC01mQJchdADaTjEA1JcJnw7O5UVmSX5BnRUQj9IIKccFNvXBHOM7Y97zc8e81hZuVWXTCO+drj1vW2NMAjXRi+n+nusS0JGKzyB7fjok0mYUP1BJhJ0PrDa/sfplJINLd6IkDqwse9ktmTUxzEb13SlSpvMNVMf6ASNAkc5h/nygFK7wgEe9R7kGe57ybGM+pWJXKkZp0nAUvtFRihAZi0DE3LHUbkN0hiaKUqRRIy7kUePzIKJ0LYT+uGdc/rQIDAQAB";
     *
     *
     * const ApiVersion = "1.0";
     * const SignType = "RSA2";
     * const PostCharset = "utf-8";//"GBK"; //GBK
     * const Format = "json"; //GBK
     * const AESKEY = "6N9IZvze0+bF1hJgOtZT5g==";
     * const SupplierId = "202008061702346558";
     *
     * const WFTPID = "2088441062310612";
     */
//"sn" => "LDN7HDQM024100905169",
//"supplier_id" => "202008061702346558",
//"biztid" => "01010QV0hq5XHtCpzQmGlOrPljB95Lw7XX9xmA9EbKcrewlxNOlaj0U",
    public $aop; //AopClient

    //接口内容加密方式
    //AES 6N9IZvze0+bF1hJgOtZT5g==

    public function __construct()
    {
        $aop = new \App\Utils\AliYun\AopClient();
        /*
            $aop->gatewayUrl = self::GatewayUrl;
            $aop->appId = self::AppID;
            $aop->rsaPrivateKey = self::RsaPrivateKKey;
            $aop->alipayrsaPublicKey = self::AlipayRasPublicKey;
            $aop->apiVersion = self::ApiVersion;
            $aop->signType = self::SignType;
            $aop->postCharset = self::PostCharset;
            $aop->format = self::Format;
            $aop->encryptKey = self::AESKEY;
            $this->aop = $aop;
        */
        $aop->gatewayUrl = config("lite.gatewayUrl");
        $aop->appId = config("lite.spiApplication.appId");
        $aop->rsaPrivateKey = config("lite.spiApplication.rsaPrivateKey");
        $aop->alipayrsaPublicKey = config("lite.spiApplication.alipayrsaPublicKey");
        $aop->apiVersion = config("lite.spiApplication.apiVersion");
        $aop->signType = config("lite.spiApplication.signType");
        $aop->postCharset = config("lite.spiApplication.postCharset");
        $aop->format = config("lite.spiApplication.format");
        $aop->encryptKey = config("lite.spiApplication.encryptKey");
        $this->aop = $aop;
    }

    //notify_type  "支付通知：PAY_SYNC；退款通知：REFUND_SYNC；撤销通知：CANCEL_SYNC。\"
    public function syncOrder(string $notify_type, array $order): array
    {

        $request = new AlipayMerchantOrderExternalPaychannelSyncRequest();
        $biz_status = "";
        switch ($order["pay_status"]) {
            case 1:
                $biz_status = "ORDER_SUCCESS";
                break;
        }

        $bizData = [
            "notify_type" => $notify_type,
            "notify_time" => date("Y-m-d H:i:s", time()),
            "out_biz_no" => $order["trade_no"],
            "biz_no" => $order["out_trade_no"],
            "biz_status" => $biz_status,
            "out_request_no" => "",
            "total_amount" => $order["total_amount"],
            "discount_amount" => $order["total_amount"],
            "mdiscount_amount" => $order["total_amount"],
            "buyer_pay_amount" => $order["total_amount"],
            "receipt_amount" => $order["total_amount"],
            "fund_bill_list" => "",
            "gmt_payment" => $order["pay_time"],//支付时间
            "pay_channel" => "",
            "refund_amount" => 0,
            "refund_total_amount" => 0,
            "origin_trade_no" => ""
        ];
        $request->setBizContent(json_encode($bizData));
        $result = $this->aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;
        if (!empty($resultCode) && $resultCode == 10000) {
            return [true, $result->$responseNode];
        } else {
            return [false, $result->$responseNode];
        }
    }


//比较签名
    protected function compareSign(array $data): bool
    {
        //签名校验计算
//        $result = $this->aop->rsaCheckV1($data, self::AlipayRasPublicKey, self::SignType);
        $result = $this->aop->rsaCheckV1($data, config("lite.spiApplication.alipayrsaPublicKey"), config("lite.spiApplication.signType"));

        return $result;
    }

    protected function getSign(array $data): string
    {

        //签名校验计算
//        $strContent = $this->aop->getSignContent($data);
        $strContent = json_encode($data);
//        $sign = $this->aop->alonersaSign($strContent, self::RsaPrivateKKey, self::SignType, false);
        $sign = $this->aop->alonersaSign($strContent, config("lite.spiApplication.rsaPrivateKey"), config("lite.spiApplication.signType"), false);
        return $sign;
    }

//支付逻辑
//{"terminal_bind_info":"{\"store_id\":\"202289152247162424\",\"store_name\":\"\\u5408\\u80a5\\u5e02\\u8700\\u5c71\\u533a\\u946b\\u98de\\u7535\\u5b50\\u7ecf\\u8425\\u90e8\",\"user_id\":1}","shop_id":"2021004190649336_308125222141217","extend_params":"{\"payment_method\":\"NFC\"}","pay_timeout":"1","total_amount":"0.02","merchant_order_no":"24110101502300700004810031179671","terminal_id":"LDN7HDQM024100905169","auth_code":"281330915280800889","sign":"pFWlQt9Tz2dZPnHgPfGOYAejeQUOWT3DFffLQnrJET2TOIHSZo63ahArQf4PvEo1YwMHOvz+NmDBLts29B/yr8uvaTkbohiPq9kXGl6L5PgKJovs07bKSvhcTPGzAxuLDjEnB52v05B/3EBMFItgDXblB7gjoQ1c0ZzdWtNl7nhj51xFIeFreJpnl+OBOzb0+5lC0M6FR4/2LXiUDJB+A8/wi8PDLRxFiV5r193Pu8vuSD/D1LTzinvIt4UtYwInHw1NCNmjO84K7VjjRPb10UQteiLfBFBftqaUsIKp0dUl7ZtfVcFqvsJiHYcuYrKrBP0gWqfV+l2Y/l+GN29xUQ==","method":"spi.alipay.merchant.order.commonisv.pay","charset":"UTF-8","version":"1.0","merchant_app_id":"2021004190649336","utc_timestamp":"1730431096","sign_type":"RSA2"}
    public function paySPI(array $requestArray): array
    {
        //spi.alipay.merchant.order.commonisv.pay
        $publicData = [
            "sign" => $requestArray["sign"],
            "method" => $requestArray["method"],
            "version" => $requestArray["version"],
            "utc_timestamp" => $requestArray["utc_timestamp"],
            "sign_type" => $requestArray["sign_type"],
            "terminal_bind_info" => $requestArray["terminal_bind_info"],
            "shop_id" => $requestArray["shop_id"],
            "pay_timeout" => $requestArray["pay_timeout"],
            "total_amount" => $requestArray["total_amount"],
            "merchant_order_no" => $requestArray["merchant_order_no"],  //商家系统内唯一订单号，对服务商为外部订单号。
            "terminal_id" => $requestArray["terminal_id"],
            "auth_code" => $requestArray["auth_code"],
            "charset" => $requestArray["charset"],
//            "cashier_id" => $requestArray["cashier_id"] ?? "",
//            "terminal_info" => $requestArray["terminal_info"] ?? "",
            //额外参数
//            "subject" => $requestArray["subject"] ?? "",
            "extend_params" => $requestArray["extend_params"] ?? "",
            "merchant_app_id" => $requestArray["merchant_app_id"] ?? ""
//            "attach_params" => $requestArray["attach_params"] ?? ""
        ];
        //重新校验
//        $flag = $this->aop->rsaCheckV1($data, null, self::SignType);
        //签名校验
        Log::channel("notify-pay")->info("pay-start", $requestArray);
        try {
            $result = $this->compareSign($requestArray);
            if (empty($result)) {
                throw new \Exception("SYSTEM_ERROR:系统繁忙:签名校验失败");
            }
            $sn = $publicData["terminal_id"];
            $store_id = ""; //店铺ID
            $user_id = 0; //代理商ID
            if (!empty($publicData["terminal_bind_info"])) {
                $terminal_bind_info = json_decode($publicData["terminal_bind_info"], true);
                $store_id = $terminal_bind_info["store_id"];
                $user_id = $terminal_bind_info["user_id"];
            }
            $pay_method = "lite_scan";
            if (!empty($publicData["extend_params"])) {
                $extend_params = json_decode($publicData["extend_params"], true);
                $pay_method = $extend_params["payment_method"] ?? "";
            }
            //BIZ_ERROR	业务异常
            //在这里处理支付逻辑
            $device = Device::query()->where("store_id", $store_id)->where("device_no", $sn)->first();
            if (empty($device)) {
                throw new \Exception("BIZ_ERROR:业务异常:设备未绑定店铺");
            }
            $store = Store::query()->where("store_id", $device->store_id)->first();
            if (empty($store)) {
                throw new \Exception("BIZ_ERROR:业务异常:门店不存在");
            }
            //关闭的商户禁止交易
            if ($store->is_close || $store->is_admin_close || $store->is_delete || $store->state == 3) {
                throw new \Exception("BIZ_ERROR:业务异常:商户已经关闭");
            }

            if(isset($store->status) && $store->status!=1){
                throw new \Exception("BIZ_ERROR:业务异常:商户已经关闭");
            }

            if ($store->pid > 0) {
                $pStore = Store::query()->where("id", $store->pid)->first();
                if ($pStore->state == 3) {
                    throw new \Exception("BIZ_ERROR:业务异常:商户已经关闭");
                }
            }
            //解析用户的付款码
            $pay_type = substr($publicData["auth_code"], 0, 2);
            $channel_type = 0;
            if (in_array($pay_type, ['25', '26', '27', '28', '29', '30'])) {
                //支付宝
                $ways_source = "alipay";
                $channel_type = "001";
            } else if (in_array($pay_type, ['10', '11', '12', '13', '14', '15'])) {
                //微信
                $ways_source = "weixin";
                $channel_type = "002";
            } else if (in_array($pay_type, ['62'])) {
                //银联
                $ways_source = "unionpay";
                $channel_type = "007";
            }
            if (empty($channel_type)) {
                throw new \Exception("BIZ_ERROR:业务异常:支付方式异常");
            }

            //在这里发起支付
            $pay_obj = new PayBaseController();
            $data = [
                'config_id' => $store->config_id,
                'merchant_id' => 0,
                'merchant_name' => "",
                'code' => $publicData["auth_code"],
                'total_amount' => $publicData["total_amount"],
                'shop_price' => 0,
                'remark' => "碰一碰支付",
                'device_id' => $device->device_no,
                'shop_desc' => "",
                'store_id' => $store_id,
                'other_no' => $publicData["merchant_order_no"],
                'couponDetail' => "",
                "pay_method" => $pay_method,
                "shop_name" => $store->store_name
            ];
            $scan_pay_public = $pay_obj->scan_pay_public($data);
//            'status' => 1,
//                'pay_status' => '1',
//                'message' => '支付成功',
//                'data' => [
//                'out_trade_no' => $out_trade_no,
//                'ways_type' => $ways_type,
//                'total_amount' => $total_amount,
//                'store_id' => $store_id,
//                'store_name' => $store_name,
//                'config_id' => $config_id,
//                'pay_time' => $pay_time,
//                'trade_no' => $trade_no,
//                'ways_source' => $data['ways_source'],
//            ]
            $result = json_decode($scan_pay_public, true);
            Log::channel("notify-pay")->info("pay-scan_pay_public", $result);
            if (!isset($result["status"])) {
                Log::channel("notify-pay")->error("pay-status", $result);
            }
            //在这里处理支付结果
            if (isset($result["status"]) && $result["status"] == 2) {
                throw new \Exception("BIZ_ERROR:业务异常:" . $result["message"]);
            }
            $msg = $result["message"];
            $order_state = "WAIT_PAY";
            $pay_time = "";
            if ($result["status"] == 1 && $result["pay_status"] == 1) {
                $order_state = "ORDER_SUCCESS";
                $pay_time = $result["data"]["pay_time"];
            } else if ($result["status"] == 1 && $result["pay_status"] == 2) {
                $order_state = "WAIT_PAY";
            } else if ($result["status"] == 1 && $result["pay_status"] == 3) {
                $order_state = "ORDER_CLOSED";
            }
            Log::channel("notify-pay")->error("pay-success", $result);
//            $requestArray["terminal_bind_info"] = json_decode($requestArray["terminal_bind_info"], true);
//            $requestArray["extend_params"] = json_decode($requestArray["extend_params"], true);
            $response = [
                "code" => "10000",//
                "msg" => "Success",
                "merchant_order_no" => $publicData["merchant_order_no"],
                "isv_order_no" => $result["data"]["out_trade_no"] ?? "",
                "channel_order_no" => $result["data"]["trade_no"] ?? '',
                "channel_type" => $channel_type,
                "order_state" => $order_state,
                "pay_time" => $pay_time,
                "total_amount" => $publicData["total_amount"],
                "receipt_amount" => $publicData["total_amount"],
                "buyer_pay_amount" => $publicData["total_amount"],
                "buyer_user_id" => "",
                "open_id" => "",
                "buyer_account_name" => "",
                "attach_params" => json_encode($requestArray),
                "error_code" => 1,
                "error_desc" => $msg
            ];

        } catch (\Exception $e) {
            Log::channel("notify-pay")->error("pay-error" . $e->getMessage() . $e->getFile() . $e->getLine());
            //解析字符串
            $response = $this->getErrorResponse($e);
        }
        //成功响应参数
        $sign = $this->getSign($response);
        return [
            "response" => $response,
            "sign" => $sign
        ];
    }

//支付查询
    public function payQuerySPI(array $requestArray): array
    {
        /**spi.alipay.merchant.order.commonisv.query
         * sign=***&method=spi.alipay.merchant.order.commonisv.query&version=1.0&utc_timestamp=1728489599&sign_type=RSA2&terminal_bind_info={"cust_id":"88888","shop_id":"6666"}&merchant_order_no=2410090150230021513&isv_order_no=241009082221513&charset=UTF-8
         **/
        $publicData = [
            "sign" => $requestArray["sign"],
            "method" => $requestArray["method"],
            "version" => $requestArray["version"],
            "utc_timestamp" => $requestArray["utc_timestamp"],
            "sign_type" => $requestArray["sign_type"],
            "charset" => $requestArray["charset"],
//            "biz_app_id" => $requestArray["biz_app_id"],
//            "invoke_app_id" => $requestArray["invoke_app_id"],
            //额外参数
            "merchant_order_no" => $requestArray["merchant_order_no"],
            "isv_order_no" => $requestArray["isv_order_no"] ?? "",
            "terminal_bind_info" => $requestArray["terminal_bind_info"],
            "terminal_id" => $requestArray["terminal_id"] ?? "",
            "shop_id" => $requestArray["shop_id"] ?? "",
            "casher_id" => $requestArray["casher_id"] ?? ""
        ];
        Log::channel("notify-query")->info("payQuery-start", $requestArray);
        try {
            $result = $this->compareSign($requestArray);
            if (empty($result)) {
                throw new \Exception("BIZ_ERROR:业务异常:签名校验失败");
            }
            $out_trade_no = $publicData["isv_order_no"];//isv_order_no
            $device_no = $publicData["terminal_id"];//terminal_id
            $other_no = $publicData["merchant_order_no"];//


            $store_id = ""; //店铺ID
            $user_id = 0; //代理商ID
            if (!empty($publicData["terminal_bind_info"])) {
                $terminal_bind_info = json_decode($publicData["terminal_bind_info"], true);
                $store_id = $terminal_bind_info["store_id"];
                $user_id = $terminal_bind_info["user_id"];
                $device_no = $terminal_bind_info["device_no"] ?? "";
                if (empty($device_no)) {
                    $device_no = $terminal_bind_info["device_no"] ?? "";
                }
            }
            //查询订单状态
            $device = Device::query()->where('store_id', $store_id)->where('device_no', $device_no)->first();
            if (empty($device)) {
                throw new \Exception("BIZ_ERROR:业务异常:设备未绑定");
            }
            $store = Store::query()->where('store_id', $store_id)
                ->select('config_id', 'merchant_id', 'pid')
                ->first();
            if (empty($store)) {
                throw new \Exception("BIZ_ERROR:业务异常:门店ID不存在");
            }
            $order = null;
            if (!empty($out_trade_no)) {
                $order = Order::query()->where("out_trade_no", $out_trade_no)->first();
            }

            if (!empty($other_no) && empty($order)) {
                $order = Order::query()->where("other_no", $other_no)->first();
            }
            //订单
            if (empty($order)) {
                throw new \Exception("ORDER_NOT_EXIST:订单不存在:订单不存在");
            }
            Log::channel("notify-query")->info("payQuery-pay_status", [
                "pay_status" => $order->pay_status,
                "out_trade_no" => $order->out_trade_no,
                "other_no" => $other_no
            ]);
            switch ($order->pay_status) {
                case 1:
                    $order_state = "ORDER_SUCCESS";
                    break;
                case 6:
                    $order_state = "REFUND_SUCCESS";
                    break;
                default:
                    $data = [
                        'out_trade_no' => $order->out_trade_no,
                        'other_no' => "",
                        'store_id' => $order->store_id,
                        'ways_type' => $order->ways_type,
                        'config_id' => $store->config_id,
                    ];
                    $order_obj = new OrderController();
                    $return = $order_obj->order_foreach_public($data);
                    if (!is_array($return)) {
                        $return = json_decode($return, true);
                    }
                    //处理return
                    if ($return["status"] == 1 && $return['pay_status'] == 2) {
                        $order_state = "WAIT_PAY";
//                    throw new \Exception("BIZ_ERROR:业务异常:".$return['message']);
                    } else if ($return["status"] == 1 && $return["pay_status"] == 1) {
                        $order_state = "ORDER_SUCCESS";
                    } else {
                        $order_state = "WAIT_PAY";
                    }
            }
            Log::channel("notify-query")->info("OrderSTATUS:" . $order->out_trade_no . "-状态:" . $order_state);
            $channel_type = "100";
            if ($order->ways_source == "alipay") {
                //支付宝
                $channel_type = "001";
            } else if ($order->ways_source == "weixin") {
                //微信
                $channel_type = "002";
            } else if ($order->ways_source == "unionpay") {
                //银联
                $channel_type = "007";
            }

            $response = [
                "code" => "10000",//
                "msg" => "Success",
//                "sub_code" => 1,
//                "sub_msg" => $message,
                "merchant_order_no" => $order->other_no,
                "isv_order_no" => $order->out_trade_no,
                "channel_order_no" => $order->trade_no,
                "channel_type" => $channel_type,
//                "cashier_id" => "",
//                "cashier_name" => "",
                "terminal_id" => $device_no,
//                "subject" => "",
                "order_state" => $order_state,
                "pay_time" => $order->pay_time,
                "total_amount" => $order->total_amount,
                "receipt_amount" => $order->total_amount,
//                "buyer_pay_amount" => $order->total_amount,
//                "refund_process_amount" => 0,
//                "refund_accept_amount" => 0,
//                "refund_success_amount" => 0,
//                "buyer_user_id" => 0,
//                "buyer_account_name" => "",
//                "attach_params" => "",
//                "error_code" => "",
//                "error_desc" => ""
            ];
        } catch (\Exception $e) {
            $response = $this->getErrorResponse($e);
        }

        //成功响应参数
        $sign = $this->getSign($response);
        return [
            "response" => $response,
            "sign" => $sign
        ];
    }

//账单查询
    public function billQuerySPI(array $requestArray): array
    {
        //spi.alipay.merchant.order.commonisv.bill.query
        $publicData = [
            "bill_merchant_no" => $requestArray["bill_merchant_no"],
            "terminal_bind_info" => $requestArray["terminal_bind_info"],
            "terminal_id" => $requestArray["terminal_id"] ?? ""
        ];
        $trade_no = $publicData["bill_merchant_no"];
        $device_no = $publicData["terminal_id"];
        $store_id = "";
        if (!empty($publicData["terminal_bind_info"])) {
            $terminal_bind_info = json_decode($publicData["terminal_bind_info"], true);
            $store_id = $terminal_bind_info["store_id"];
            $device_no = empty($device_no) ? $terminal_bind_info["device_no"] : $device_no;
        }
        try {
            //查询订单状态
            $device = Device::query()->where('store_id', $store_id)->where('device_no', $device_no)->first();
            if (empty($device)) {
                throw new \Exception("BIZ_ERROR:业务异常:设备未绑定");

            }
            $store = Store::query()->where('store_id', $store_id)
                ->select('config_id', 'merchant_id', 'pid')
                ->first();
            if (empty($store)) {
                throw new \Exception("BIZ_ERROR:业务异常:门店ID不存在");
            }

            $order = Order::query()->where("trade_no", $trade_no)->first();
            if (empty($order)) {
                throw new \Exception("ORDER_NOT_EXIST:订单不存在:订单不存在");
            }

            $response = [
                "code" => "10000",//
                "msg" => "Success",
//                "sub_code" => 1,
//                "sub_msg" => $message,
                "merchant_order_no" => $order->other_no,
                "isv_order_no" => $order->out_trade_no,
                "channel_order_no" => $order->trade_no,
                "channel_type" => $this->channel_type($order->toArray()),
//                "cashier_id" => "",
//                "cashier_name" => "",
                "terminal_id" => $device_no,
//                "subject" => "",
                "order_state" => $this->order_state($order),
                "pay_time" => $order->pay_time,
                "total_amount" => $order->total_amount,
                "receipt_amount" => $order->total_amount,
                "refund_process_amount" => $order->refund_amount,
                "refund_accept_amount" => $order->refund_amount,
                "refund_success_amount" => $order->refund_amount,
            ];

        } catch (\Exception $e) {
            $response = $this->getErrorResponse($e);
        }

        $sign = $this->getSign($response);
        return [
            "response" => $response,
            "sign" => $sign
        ];
    }


    public function order_state(Order $order): string
    {
        $order_state = "";
        $pay_status = $order->pay_status;
        switch ($pay_status) {
            case 1:
                $order_state = "ORDER_SUCCESS";
                break;
            case 2:
                $order_state = "WAIT_PAY";
                break;
            case 3:
                $order_state = "ORDER_CLOSED";
                break;
        }
        return $order_state;
    }


    public function channel_type(array $order): string
    {
        $channel_type = "100";
        if ($order["ways_source"] == "alipay") {
            //支付宝
            $channel_type = "001";
        } else if ($order["ways_source"] == "weixin") {
            //微信
            $channel_type = "002";
        } else if ($order["ways_source"] == "unionpay") {
            //银联
            $channel_type = "007";
        }
        return $channel_type;
    }


    public function refundAuthCodeSPI(array $requestArray): array
    {
        //spi.alipay.commerce.refundauthcode.apply
        $publicData = [
            "sign" => $requestArray["sign"],
            "method" => $requestArray["method"],
            "version" => $requestArray["version"],
            "utc_timestamp" => $requestArray["utc_timestamp"],
            "sign_type" => $requestArray["sign_type"],
            "charset" => $requestArray["charset"],
//            "biz_app_id" => $requestArray["biz_app_id"],
//            "invoke_app_id" => $requestArray["invoke_app_id"],
            //额外参数
            "terminal_bind_info" => $requestArray["terminal_bind_info"],
            "terminal_id" => $requestArray["terminal_id"] ?? "",
            "shop_id" => $requestArray["shop_id"] ?? "",
            "casher_id" => $requestArray["casher_id"] ?? "",
            "out_biz_no" => $requestArray["out_biz_no"],
            "order_no" => $requestArray["order_no"] ?? "",
        ];

        try {
            $ch = $this->compareSign($requestArray);
            if (empty($ch)) {
                throw new \Exception("BIZ_ERROR:业务异常:签名校验失败");
            }

            $response = [
                "code" => "10000",//
                "msg" => "Success",
//                "sub_code" => 1,
//                "sub_msg" => $message,
                "grant_result" => true,
                "grant_path" => "SMS",
                "error_code" => "NO_PRIMITION",
                "error_desc" => "权限不足"
            ];
        } catch (\Exception $e) {
            $response = $this->getErrorResponse($e);
        }
        $sign = $this->getSign($response);
        return [
            "response" => $response,
            "sign" => $sign
        ];
    }


//退款SPI
    public function refundSPI(array $requestArray): array
    {
        //spi.alipay.merchant.order.commonisv.refund
        $publicData = [
            "method" => $requestArray["method"],
            "charset" => $requestArray["charset"],
            "version" => $requestArray["version"],
//            "biz_app_id" => $requestArray["biz_app_id"],
//            "invoke_app_id" => $requestArray["invoke_app_id"],
            "utc_timestamp" => $requestArray["utc_timestamp"],
            "sign_type" => $requestArray["sign_type"],
            "sign" => $requestArray["sign"],

            //
            "merchant_order_no" => $requestArray["merchant_order_no"],
            "isv_order_no" => $requestArray["isv_order_no"],
            "merchant_refund_no" => $requestArray["merchant_refund_no"],
            "refund_amount" => $requestArray["refund_amount"],
            "terminal_bind_info" => $requestArray["terminal_bind_info"],
            "terminal_id" => $requestArray["terminal_id"],

            "shop_id" => $requestArray["shop_id"] ?? "",
            "cashier_id" => $requestArray["cashier_id"] ?? "",
            "auth_code" => $requestArray["auth_code"] ?? "",
        ];

        try {

            $ch = $this->compareSign($requestArray);
            if (empty($ch)) {
                throw new \Exception("BIZ_ERROR:业务异常:签名校验失败");
            }
            $device_no = $publicData["terminal_id"];
            $store_id = '';
            if (!empty($publicData["terminal_bind_info"])) {
                $terminal_bind_info = json_decode($publicData["terminal_bind_info"], true);
                $store_id = $terminal_bind_info["store_id"];
                $device_no = empty($device_no) ? $terminal_bind_info["device_no"] : $device_no;
            }
            $device = Device::query()->where('store_id', $store_id)
                ->where('device_no', $device_no)
                ->first();
            if (empty($device)) {
                throw new \Exception("BIZ_ERROR:业务异常:设备未绑定");
            }
            $store = Store::query()->where('store_id', $store_id)
                ->select('config_id', 'merchant_id', 'pid')
                ->first();
            if (empty($store)) {
                throw new \Exception("NO_PERMISSION:无权限退款:门店ID不存在");
            }
            $out_trade_no = $publicData["isv_order_no"];
            $order = Order::query()->where("out_trade_no", $out_trade_no)->first();
            if (empty($order)) {
                throw new \Exception("NO_PERMISSION:无权限退款:订单不存在");
            } else if ($order->pay_status != 1) {
                throw new \Exception("ORDER_NOT_PAID:订单还未完成支付:订单未支付，无法退款");
            }

            //请求参数
            $data = [
                'merchant_id' => $device->merchant_id,
                'out_trade_no' => $out_trade_no,
                'refund_amount' => $publicData["refund_amount"],
                'refund_no' => $publicData["merchant_refund_no"],
            ];
            $pay_obj = new OrderController();
            $scan_pay_public = $pay_obj->refund_public($data);
            if (!is_array($scan_pay_public)) {
                $scan_pay_public = json_decode($scan_pay_public, true);
            }
            //在这里操作结果
//        'status' => '2',
//                    'message' => '退款金额大于总金额'
            if ($scan_pay_public["status"] == 2) {
                //退款失败
                $response = [
                    "code" => "40004",
                    "msg" => "Business Failed",
                    "sub_code" => "SYSTEM_ERROR",
                    "sub_msg" => $scan_pay_public["message"],
                    "error_code" => -1,
                    "error_msg" => $scan_pay_public["message"]
                ];
            } else if ($scan_pay_public["status"] == 1) {
                //退款操作成功
//            $data = [
//                'refund_amount' => $refund_amount,
//                'out_trade_no' => $out_trade_no,
//                'refund_no' => $return['data']['outOrderNo'], //联动流水号
//                'other_no' => $other_no
//            ];
                $response = [
                    "code" => "10000",
                    "msg" => "Success",
                    "merchant_order_no" => $publicData["merchant_order_no"],
                    "isv_order_no" => $publicData["isv_order_no"],
                    "merchant_refund_no" => $publicData["merchant_refund_no"],
                    "isv_refund_no" => $scan_pay_public["data"]["refund_no"],
                    "channel_refund_no" => $scan_pay_public["data"]["refund_no"],
                    "refund_state" => "SUCCESS",
                    "finish_time" => "",
                    "refund_amount" => $scan_pay_public["data"]["refund_amount"],
                    "error_code" => "",
                    "error_desc" => ""
                ];
            }
        } catch (\Exception $e) {
            $response = $this->getErrorResponse($e);
        }
        $sign = $this->getSign($response);
        return [
            "response" => $response,
            "sign" => $sign
        ];

    }

//退款查询
//spi.alipay.merchant.order.commonisv.refund.query
    public function refundQuerySPI(array $requestArray): array
    {
        $publicData = [
            "method" => $requestArray["method"],
            "charset" => $requestArray["charset"],
            "version" => $requestArray["version"],
//            "biz_app_id" => $requestArray["biz_app_id"],
//            "invoke_app_id" => $requestArray["invoke_app_id"],
            "utc_timestamp" => $requestArray["utc_timestamp"],
            "sign_type" => $requestArray["sign_type"],
            "sign" => $requestArray["sign"],

            //body参数
            "merchant_order_no" => $requestArray["merchant_order_no"],
            "isv_order_no" => $requestArray["isv_order_no"],
            "merchant_refund_no" => $requestArray["merchant_refund_no"],
            "isv_refund_no" => $requestArray["isv_refund_no"],
            "terminal_bind_info" => $requestArray["terminal_bind_info"],
            "terminal_id" => $requestArray["terminal_id"],
            "shop_id" => $requestArray["shop_id"] ?? ""
        ];
        try {

            $ch = $this->compareSign($requestArray);
            if (empty($ch)) {
                throw new \Exception("BIZ_ERROR:业务异常:签名校验失败");
            }

            $store_id = "";
            $device_no = $publicData["terminal_id"];
            if (!empty($publicData["terminal_bind_info"])) {
                $terminal_bind_info = json_decode($publicData["terminal_bind_info"], true);
                $store_id = $terminal_bind_info["store_id"];
                $device_no = empty($device_no) ? $terminal_bind_info["device_no"] : $device_no;
            }

            $device = Device::query()->where('store_id', $store_id)
                ->where('device_no', $device_no)
                ->first();
            if (empty($device)) {
                throw new \Exception("BIZ_ERROR:业务异常:设备未绑定");
            }
            $store = Store::query()->where('store_id', $store_id)
                ->select('config_id', 'merchant_id', 'pid')
                ->first();
            if (empty($store)) {
                throw new \Exception("BIZ_ERROR:业务异常:门店ID不存在");
            }

            $out_trade_no = $publicData["isv_order_no"];
            $device_no = $publicData["terminal_id"];
            $refund_no = $publicData["isv_refund_no"];
            $order = Order::query()->where('device_id', $device_no)
                ->where('out_trade_no', $out_trade_no)
                ->select('refund_amount', 'out_trade_no')->first();
            if (empty($order)) {
                throw new \Exception("BIZ_ERROR:业务异常:订单不存在");
            }

            $refundOrder = RefundOrder::query()->where([
                "out_trade_no" => $out_trade_no,
                "refund_no" => $refund_no
            ])->first();
            if (empty($refundOrder)) {
                throw new \Exception("RECORD_NOT_EXIST:退款单据不存在	:退款订单不存在");
            }
            $response = [
                "code" => "10000",
                "msg" => "Success",
                "merchant_order_no" => $publicData["merchant_order_no"],
                "isv_order_no" => $publicData["isv_order_no"],
                "merchant_refund_no" => $publicData["merchant_refund_no"],
                "isv_refund_no" => $publicData["isv_refund_no"],
                "channel_refund_no" => $publicData["channel_refund_no"],
                "refund_state" => "",
                "finish_time" => "",
                "refund_amount" => "",
                "error_code" => "",
                "error_desc" => ""
            ];
        } catch (\Exception $e) {
            $response = $this->getErrorResponse($e);
        }
        $sign = $this->getSign($response);
        return [
            "response" => $response,
            "sign" => $sign
        ];
    }

    public function getErrorResponse(\Exception $e): array
    {
        $error = explode(":", $e->getMessage());
        $response = [
            "code" => "40004",
            "msg" => "Business Failed",
            "sub_code" => count($error) != 3 ? "SYSTEM_ERROR" : $error[0],
            "sub_msg" => count($error) != 3 ? "系统繁忙" : $error[1],
            "error_code" => -1,
            "error_msg" => count($error) != 3 ? $error[0] : $error[2],
        ];
        return $response;
    }

//明细
    public function billDetailQuerySPI(array $requestArray): array
    {
        //spi.alipay.commerce.billdetail.query
        $publicData = [
            "method" => $requestArray["method"],
            "charset" => $requestArray["charset"],
            "version" => $requestArray["version"],
//            "biz_app_id" => $requestArray["biz_app_id"],
//            "invoke_app_id" => $requestArray["invoke_app_id"],
            "utc_timestamp" => $requestArray["utc_timestamp"],
            "sign_type" => $requestArray["sign_type"],
            "sign" => $requestArray["sign"],

            "terminal_id" => $requestArray["terminal_id"],
            "terminal_bind_info" => $requestArray["terminal_bind_info"],
//            "shop_id" => $requestArray["shop_id"],
//            "cashier_id" => $requestArray["cashier_id"],
            "date" => $requestArray["date"],
            "page_num" => $requestArray["page_num"] ?? 1,
            "page_size" => $requestArray["page_size"] ?? 10
        ];

        //在这里处理账单数据

        //处理数据
        try {
            $ch = $this->compareSign($requestArray);
            if (empty($ch)) {
                throw new \Exception("BIZ_ERROR:业务异常:签名校验失败");
            }
            $store_id = "";
            $device_no = $publicData["terminal_id"];
            if (!empty($publicData["terminal_bind_info"])) {
                $terminal_bind_info = json_decode($publicData["terminal_bind_info"], true);
                $store_id = $terminal_bind_info["store_id"];
                $device_no = empty($device_no) ? $terminal_bind_info["device_no"] : $device_no;
            }

            $device = Device::query()->where('store_id', $store_id)
                ->where('device_no', $device_no)
                ->first();
            if (empty($device)) {
                throw new \Exception("BIZ_ERROR:业务异常:设备未绑定");
            }
            $store = Store::query()->where('store_id', $store_id)
                ->select('config_id', 'merchant_id', 'pid')
                ->first();
            if (empty($store)) {
                throw new \Exception("BIZ_ERROR:业务异常:门店ID不存在");
            }
            //开始查看流水
            $date = $publicData["date"];
            $service = new MerchantBillCountService();

            list($total_size, $orderList) = $service->liteDeviceLog(
                [
                    "page" => $publicData["page_num"],
                    "pagesize" => $publicData["page_size"],
                ],
                [
                    "store_id" => $store_id,
                    "device_no" => $device_no,
                    "date" => $date
                ]
            );
            $response = [
                "code" => "10000",
                "msg" => "Success",
                "total_size" => $total_size,
//                "error_code" => "",
//                "error_desc" => "",
                "order_list" => $orderList
            ];
        } catch (\Exception $e) {
            $response = $this->getErrorResponse($e);
        }
        $sign = $this->getSign($response);
        return [
            "sign" => $sign,
            "response" => $response
        ];

    }


//统计
    public function billStaticQuerySPI(array $requestArray): array
    {
        //spi.alipay.commerce.billstatistics.query
        $publicData = [
            "method" => $requestArray["method"],
            "charset" => $requestArray["charset"],
            "version" => $requestArray["version"],
//            "biz_app_id" => $requestArray["biz_app_id"],
//            "invoke_app_id" => $requestArray["invoke_app_id"],
            "utc_timestamp" => $requestArray["utc_timestamp"],
            "sign_type" => $requestArray["sign_type"],
            "sign" => $requestArray["sign"],

            "terminal_bind_info" => $requestArray["terminal_bind_info"],
            "terminal_id" => $requestArray["terminal_id"],
//            "shop_id" => $requestArray["shop_id"],
//            "cashier_id" => $requestArray["cashier_id"],
            "date" => $requestArray["date"] ?? date("Y-m-d H:i:s", time())
        ];

        try {
            $ch = $this->compareSign($requestArray);
            if (empty($ch)) {
                throw new \Exception("BIZ_ERROR:业务异常:签名校验失败");
            }
            $store_id = "";
            $device_no = $publicData["terminal_id"];
            if (!empty($publicData["terminal_bind_info"])) {
                $terminal_bind_info = json_decode($publicData["terminal_bind_info"], true);
                $store_id = $terminal_bind_info["store_id"];
                $device_no = empty($device_no) ? $terminal_bind_info["device_no"] : $device_no;
            }

            $device = Device::query()->where('store_id', $store_id)
                ->where('device_no', $device_no)
                ->first();
            if (empty($device)) {
                throw new \Exception("BIZ_ERROR:业务异常:设备未绑定");
            }
            $store = Store::query()->where('store_id', $store_id)
                ->select('config_id', 'merchant_id', 'pid')
                ->first();
            if (empty($store)) {
                throw new \Exception("BIZ_ERROR:业务异常:门店ID不存在");
            }
            $date = $publicData["date"];
            $service = new MerchantBillCountService();
            $count = $service->merchantGet(
                [
                    "startDate" => date("Y-m-d 00:00:00", strtotime($date)),
                    "endDate" => date("Y-m-d 23:59:59", strtotime($date)),
                    "store_id" => $store_id,
                    "device_no" => $device_no,
                    "curHdIndex" => 0
                ]
            );
            $response = [
                "code" => "10000",
                "msg" => "Success",
                "statistic_time" => date("Y-m-d 00:00:00", strtotime($date)),
                "receipt_amount" => (float)$count["total_fee"],
                "receipt_count" => (float)$count["total_num"],
                "refund_amount" => (float)$count["refund_fee"],
                "refund_count" => (float)$count["refund_num"],
                "total_income" => (float)$count["total_fee"] - (float)$count["refund_fee"],
                "error_code" => "",
                "error_desc" => ""
            ];
        } catch (\Exception $e) {
            $response = $this->getErrorResponse($e);
        }
        $sign = $this->getSign($response);
        return [
            "response" => $response,
            "sign" => $sign
        ];

    }
}